<template>
  <div class="z-table">
    <!-- 头部按钮-->
    <div class="z-table-btn-group">
      <slot name="topMenu"></slot>
    </div>
    <!-- 表格 -->
    <el-table
      :data="tableData"
      ref="table"
      v-on="setTableOn()"
      v-bind="setTableBind()"
    >
      <template v-for="(o, i) in tableOption.column">
        <!-- 序号和选中 -->
        <el-table-column
          :key="'item' + i"
          v-if="o.type && !o.prop"
          :index="getIndex"
          v-bind="setTableItemBind(o)"
          :width="o.width || 60"
        />
        <!-- 插槽 -->
        <el-table-column
          :key="'item' + i"
          v-else-if="o.slot"
          v-bind="setTableItemBind(o)"
        >
          <template #default="{ row, column, $index }">
            <div class="z-cell">
              <slot
                :name="o.prop"
                :row="row"
                :column="column"
                :$index="$index"
              ></slot>
            </div>
          </template>
        </el-table-column>
        <!-- 字典 -->
        <el-table-column
          :key="'item' + i"
          v-else-if="o.dicData"
          v-bind="setTableItemBind(o)"
        >
          <template #default="{ row }">
            <div class="z-cell">
              {{ transDicData(row, o) }}
            </div>
          </template>
        </el-table-column>
        <!-- 针对其他默认情况 -->
        <el-table-column :key="'item' + i" v-else v-bind="setTableItemBind(o)">
        </el-table-column>
      </template>
    </el-table>
    <!-- 分页 -->
    <div class="pagination-box">
      <el-pagination
        ref="pagination"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :page-size.sync="pageParams.pageSize"
        :current-page.sync="pageParams.pageNo"
        :total="total"
        v-bind="setPaginationBind()"
        v-on="setPaginationOn()"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
// 需要根据系统修改接口分页的参数
export default {
  props: {
    // 表格的所有配置项
    tableOption: {
      type: Object,
      default: () => {},
    },
    // 搜索条件
    queryParams: {
      type: Object,
      default: () => {
        return {};
      },
    },
    disabled: {
      type: Boolean,
      default: () => false,
    },
    loading: {
      type: Boolean,
      default: () => false,
    },
  },
  data() {
    return {
      pageParams: {
        pageSize: 10,
        pageNo: 1,
      },
      total: 0,
      tableData: [],
      // 默认的表格配置
      tableConfig: {
        stripe: true,
        border: true,
        // size: "mini",
      },
      tableItemConfig: {
        align: "center",
        headerAlign: "center",
        minWidth: 60,
        width: null,
      },
      paginationConfig: {
        background: true,
        hideOnSinglePage: false,
        layout: "total, sizes, prev, pager, next, jumper",
        pageSizes: [10, 20, 30, 40, 50, 100],
      },
      funsArr: [
        "clearSelection",
        "toggleRowSelection",
        "toggleAllSelection",
        "toggleRowExpansion",
        "setCurrentRow",
        "clearSort",
        "clearFilter",
        "doLayout",
        "sort",
      ],
    };
  },
  mounted() {
    if (this.tableOption.autoRequest !== false) {
      this.handleQuery(true);
    }
    this.initFuns();
  },
  methods: {
    handleQuery(bool) {
      if (bool) {
        this.pageParams.pageNo = 1;
      }
      const { tableOption } = this;
      const { apiRequest } = tableOption;
      if (!apiRequest) {
        return false;
      }
      apiRequest({ ...this.queryParams, ...this.pageParams }).then((res) => {
        this.tableData = res.records || [];
        this.total = res.total || 0;
      });
    },
    getIndex(index) {
      return (
        index + 1 + (this.pageParams.pageNo - 1) * this.pageParams.pageSize
      );
    },
    handleSizeChange() {
      this.handleQuery(true);
    },
    handleCurrentChange() {
      this.handleQuery();
    },
    // 字典转换
    transDicData(row, o) {
      const { dicData, prop } = o;
      const props = o.props || {
        label: "label",
        value: "value",
      };
      const selectOne = dicData.filter((item) => {
        return item[props.value] === row[prop];
      });
      return (selectOne.length === 1 && selectOne[0][props.label]) || "";
    },

    setTableBind() {
      const { tableConfig } = this.tableOption;
      const obj = {
        ...this.tableConfig,
      };
      if (tableConfig) {
        Object.assign(obj, tableConfig);
      }
      return obj;
    },
    setTableItemBind(config) {
      const o = this._.cloneDeep(config);
      delete o.slot;
      const obj = {
        ...this.tableItemConfig,
        ...o,
      };
      return obj;
    },
    setPaginationBind() {
      const { paginationConfig } = this.tableOption;
      const obj = {
        ...this.paginationConfig,
        ...paginationConfig,
      };
      return obj;
    },
    setTableOn() {
      const { tableEvents } = this.tableOption;
      return {
        ...tableEvents,
      };
    },
    setPaginationOn() {
      const { paginationEvents } = this.tableOption;
      return {
        ...paginationEvents,
      };
    },
    initFuns() {
      this.funsArr.forEach((item) => {
        this[item] = (...params) => {
          this.$refs.table[item](...params);
        };
      });
    },
  },
};
</script>

<style scoped lang="less">
.z-table {
  .z-table-btn-group {
    margin-bottom: 20px;
  }
  .z-cell {
    /deep/ .el-button {
      padding: 0 !important;
    }
  }
  .pagination-box {
    text-align: right;
    /deep/ .el-pagination {
      margin-top: 20px;
    }
  }
  /deep/ .el-table {
    .el-table__header {
      .el-table__cell {
        background: rgb(239, 245, 255) !important;
        color: #333;
        font-size: 16px;
        font-weight: 400;
      }
    }
    .el-table__body {
      .el-table__cell {
        color: #333;
      }
    }
  }
}
</style>
